﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using Acme.BookStore2.Permissions;
using Microsoft.AspNetCore.Authorization;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectExtending;

namespace Acme.BookStore2
{
    [Authorize(BookStore2Permissions.VehicleRepairRecord.Default)]
    public class VehicleRepairRecordAppService : ApplicationService, IVehicleRepairRecordAppService
    {
        private readonly IVehicleRepairRecordRepository _vehicleRepairRecordRepository;
        private readonly VehicleRepairRecordManager _vehicleRepairRecordManager;

        public VehicleRepairRecordAppService(
            IVehicleRepairRecordRepository vehicleRepairRecordRepository, 
            VehicleRepairRecordManager vehicleRepairRecordManager)
        {
            _vehicleRepairRecordRepository = vehicleRepairRecordRepository;
            _vehicleRepairRecordManager = vehicleRepairRecordManager;
        }

        public async Task<VehicleRepairRecordDto> GetAsync(Guid id)
        {
            return ObjectMapper.Map<VehicleRepairRecord, VehicleRepairRecordDto>(await _vehicleRepairRecordRepository.GetAsync(id, false));
        }

        public async Task<PagedResultDto<VehicleRepairRecordDto>> GetPagedListAsync(GetVehicleRepairRecordsInput input)
        {
            var count = await _vehicleRepairRecordRepository.GetCountAsync(input.VehicleId, input.StartDateBegin, input.StartDateEnd);
            var list = await _vehicleRepairRecordRepository.GetPagedListAsync(input.SkipCount, input.MaxResultCount,
                input.Sorting, input.VehicleId, input.StartDateBegin, input.StartDateEnd);

            return new PagedResultDto<VehicleRepairRecordDto>(
                count, 
                ObjectMapper.Map<List<VehicleRepairRecord>, List<VehicleRepairRecordDto>>(list));
        }

        [Authorize(BookStore2Permissions.VehicleRepairRecord.Create)]
        public async Task<VehicleRepairRecordDto> CreateAsync(VehicleRepairRecordCreateDto input)
        {
            var vehicleRepairRecord = new VehicleRepairRecord(
                GuidGenerator.Create(),
                input.VehicleId,
                CurrentTenant.Id);

            UpdateVehicleRepairRecord(vehicleRepairRecord, input);
            input.MapExtraPropertiesTo(vehicleRepairRecord);

            await _vehicleRepairRecordRepository.InsertAsync(vehicleRepairRecord);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<VehicleRepairRecord, VehicleRepairRecordDto>(vehicleRepairRecord);
        }

        [Authorize(BookStore2Permissions.VehicleRepairRecord.Update)]
        public async Task<VehicleRepairRecordDto> UpdateAsync(Guid id, VehicleRepairRecordUpdateDto input)
        {
            var vehicleRepairRecord = await _vehicleRepairRecordRepository.GetAsync(id);
            vehicleRepairRecord.ConcurrencyStamp = input.ConcurrencyStamp;
           
            UpdateVehicleRepairRecord(vehicleRepairRecord, input);
            input.MapExtraPropertiesTo(vehicleRepairRecord);

            await _vehicleRepairRecordRepository.UpdateAsync(vehicleRepairRecord);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<VehicleRepairRecord, VehicleRepairRecordDto>(vehicleRepairRecord);
        }

        [Authorize(BookStore2Permissions.VehicleRepairRecord.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            var vehicleRepairRecord = await _vehicleRepairRecordRepository.FindAsync(id);
            if (vehicleRepairRecord == null)
            {
                return;
            }

            await _vehicleRepairRecordRepository.DeleteAsync(vehicleRepairRecord);
        }

        [Authorize(BookStore2Permissions.VehicleRepairRecord.Export)]
        public async Task ExportAsync(GetVehicleRepairRecordsInput input)
        {
        }

        private void UpdateVehicleRepairRecord(VehicleRepairRecord vehicleRepairRecord, VehicleRepairRecordCreateOrUpdateDtoBase input)
        {
            vehicleRepairRecord.StartDate = input.StartDate;
            vehicleRepairRecord.EndDate = input.EndDate;
            vehicleRepairRecord.Location = input.Location;
            vehicleRepairRecord.FollowUpPerson = input.FollowUpPerson;
            vehicleRepairRecord.Cost = input.Cost;
            vehicleRepairRecord.FailureCause = input.FailureCause;
            vehicleRepairRecord.Technician = input.Technician;
            vehicleRepairRecord.Detail = input.Detail;
            vehicleRepairRecord.Remark = input.Remark;
            
            ObjectMapper.Map(input.AttachFiles, vehicleRepairRecord.AttachFiles);
        }
    }
}